package com.zhx.beanproxy;

import java.lang.reflect.Field;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author zhx
 * @title   解决循环依赖 基本原理
 * @description
 * @date 2022/9/27 17:26
 */
public class ABclrcle {



        private final static Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

        public static void main(String[] args) throws Exception {
            System.out.println(getBean(ClazzB.class).getA());
            System.out.println(getBean(ClazzA.class).getB());
        }

        private static <T> T getBean(Class<T> beanClass) throws Exception {
            String beanName = beanClass.getSimpleName().toLowerCase();
            if (singletonObjects.containsKey(beanName)) {
                return (T) singletonObjects.get(beanName);
            }
            // 实例化对象入缓存(这时的对象还没初始化属性，暂时放入缓存)
            Object obj = beanClass.newInstance();
            singletonObjects.put(beanName, obj);
            // 属性填充补全对象
            Field[] fields = obj.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                Class<?> fieldClass = field.getType();
                String fieldBeanName = fieldClass.getSimpleName().toLowerCase();
                field.set(obj, singletonObjects.containsKey(fieldBeanName) ? singletonObjects.get(fieldBeanName) : getBean(fieldClass));
                field.setAccessible(false);
            }
            return (T) obj;
        }




}

class ClazzA {

    private ClazzB b ;

    public ClazzB getB() {
        return b;
    }

    public void setB(ClazzB b) {
        this.b = b;
    }
}

class ClazzB {

    private ClazzA a ;

    public ClazzA getA() {
        return a;
    }

    public void setA(ClazzA a) {
        this.a = a;
    }
}
